
import Foundation
import Network
import Combine

//@MainActor
public final class WebSocketManager {
    // MARK: - 配置参数
    private let url: URL
    private let session: URLSession
    private var task: URLSessionWebSocketTask?
    private let pathMonitor = NWPathMonitor()
    private var cancellables = Set<AnyCancellable>()
    private var reconnectAttempts = 0
    
    // 动态心跳间隔（Wi-Fi 25s/蜂窝40s）
    private var pingInterval: TimeInterval {
        pathMonitor.currentPath.isExpensive ? 40 : 25
    }
    
    // 状态回调
    public var onConnect: (() -> Void)?
    public var onDisconnect: ((Error?) -> Void)?
    public var onMessage: ((URLSessionWebSocketTask.Message) -> Void)?
    
    // MARK: - 初始化
    public init(url: URL, session: URLSession = .shared) {
        self.url = url
        self.session = session
        setupNetworkMonitor()
    }
    
    // MARK: - 连接控制
    public func connect() {
        guard task == nil else { return }
        
        task = session.webSocketTask(with: url)
        task?.resume()
        startMessageListener()
        scheduleHeartbeat()
        onConnect?()
    }
    
    public func disconnect() {
        task?.cancel(with: .goingAway, reason: nil)
        task = nil
        onDisconnect?(nil)
    }
    
    // MARK: - 消息处理
    public func send(_ message: String) async throws {
        guard let task = task else { throw WebSocketError.notConnected }
        try await task.send(.string(message))
    }
    
    public func send(data: Data) async throws {
        guard let task = task else { throw WebSocketError.notConnected }
        try await task.send(.data(data))
    }
    
    private func startMessageListener() {
        task?.receive { [weak self] result in
            switch result {
            case .success(let message):
                self?.onMessage?(message)
                self?.startMessageListener()
            case .failure(let error):
                self?.handleError(error)
            }
        }
    }
    
    // MARK: - 心跳机制
    private func scheduleHeartbeat() {
        Timer.publish(every: pingInterval, on: .main, in: .common)
            .autoconnect()
            .sink { [weak self] _ in
                self?.sendPing()
            }
            .store(in: &cancellables)
    }
    
    private func sendPing() {
        task?.sendPing { [weak self] error in
            error == nil ? self?.resetReconnectCount() : self?.handleFailure()
        }
    }
    
    // MARK: - 网络监控
    private func setupNetworkMonitor() {
        pathMonitor.pathUpdateHandler = { [weak self] path in
            path.status == .satisfied ? self?.connect() : self?.disconnect()
        }
        pathMonitor.start(queue: DispatchQueue.global())
    }
    
    // MARK: - 错误处理
    private func handleError(_ error: Error) {
        onDisconnect?(error)
        scheduleReconnect()
    }
    
    private func scheduleReconnect() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            self.connect()
        }
    }
    
    private func resetReconnectCount() {
        reconnectAttempts = 0  // 重置重连计数器:ml-citation{ref="1,9" data="citationList"}
    }

    private func handleFailure() {
        reconnectAttempts += 1
        let maxInterval: TimeInterval = 30
        let delay = min(pow(2, Double(reconnectAttempts)), maxInterval)  // 指数退避算法:ml-citation{ref="6,9" data="citationList"}
        
        DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
            guard let self = self else { return }
            switch self.task?.state {
            case .running, .suspended:
                self.sendPing()  // 连接仍存在时继续检测:ml-citation{ref="3" data="citationList"}
            default:
                self.connect()   // 触发重连流程:ml-citation{ref="2,6" data="citationList"}
            }
        }
    }

}

public enum WebSocketError: Error {
    case notConnected
    case invalidMessage
    case networkUnavailable
}
